#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
企业级Python控制流最佳实践示例 - 对比Java控制结构

本文件演示了Python控制流的企业级使用模式，特别针对Java工程师的理解需求：

学习重点：
1. Python条件语句 vs Java if-else
2. Python循环 vs Java for/while循环
3. Python异常处理 vs Java try-catch
4. Python上下文管理器 vs Java try-with-resources
5. Python生成器 vs Java Stream API

Java对比要点：
- Python的elif vs Java的else if
- Python的for-in vs Java的enhanced for loop
- Python的with语句 vs Java的try-with-resources
- Python的生成器 vs Java的Stream和Iterator
- Python的异常处理更简洁

作者: Python企业开发团队
创建时间: 2024-01-01
版本: 1.0.0
"""

# === 导入模块说明（对比Java import） ===
import logging      # 日志系统，类似Java的java.util.logging
import sys          # 系统相关，类似Java的System类
from contextlib import contextmanager, suppress  # 上下文管理器，类似Java的AutoCloseable
from enum import Enum, auto                       # 枚举类，类似Java的enum
from pathlib import Path                          # 路径处理，类似Java的java.nio.file.Path
from typing import Any, Dict, Generator, Iterator, List, Optional, Union  # 类型注解，类似Java泛型
from dataclasses import dataclass                 # 数据类，类似Java的record
import json         # JSON处理，类似Java的Jackson或Gson
import tempfile     # 临时文件，类似Java的java.nio.file.Files.createTempFile

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(levelname)s:%(name)s:%(message)s'
)
logger = logging.getLogger(__name__)

class ProcessingStatus(Enum):
    """处理状态枚举"""
    PENDING = auto()
    PROCESSING = auto()
    COMPLETED = auto()
    FAILED = auto()

@dataclass
class ProcessingResult:
    """处理结果数据类"""
    status: ProcessingStatus
    data: Any = None
    error_message: Optional[str] = None
    metadata: Dict[str, Any] = None

    def __post_init__(self):
        if self.metadata is None:
            self.metadata = {}

def demonstrate_enhanced_conditionals() -> None:
    """演示增强的条件语句最佳实践 - 对比Java的if-else结构
    
    🎯 概述引导：
    Python的控制流语法更简洁直观，特别是条件语句和循环结构。理解这些差异有助于写出更Pythonic的代码。
    
    📚 学习要点：
    1. elif关键字比Java的else if更简洁
    2. isinstance()比Java的instanceof更直观
    3. 海象运算符:=减少重复计算
    4. f-string比Java的String.format()更易读
    5. 链式比较（如 0 <= x <= 100）Java不支持
    
    🔍 Java对比要点：
    - Python的elif vs Java的else if
    - Python的类型检查 vs Java的instanceof
    - Python的海象运算符 vs Java的传统赋值
    - Python的f-string vs Java的String.format()
    
    💡 关键理解：
    Python的控制流语法设计更贴近自然语言，提高了代码的可读性和简洁性。
    """
    print("\n======== 1. 企业级条件语句 ========")
    print("🎯 学习目标：掌握Python控制流的简洁语法和独特特性")
    print("📖 重点概念：elif语句、链式比较、海象运算符、类型检查")
    print("-" * 60)
    
    # 使用枚举和类型注解（对比Java的泛型和枚举）
    def evaluate_score(score: Union[int, float]) -> str:
        """评估分数等级 - 对比Java的条件判断
        
        Java等价写法：
        public String evaluateScore(Number score) throws IllegalArgumentException {
            if (!(score instanceof Integer || score instanceof Double)) {
                throw new IllegalArgumentException("分数必须是数字类型");
            }
            double value = score.doubleValue();
            if (value < 0 || value > 100) {
                throw new IllegalArgumentException("分数必须在0-100之间");
            }
            
            double normalizedScore = value / 100;
            if (normalizedScore >= 0.9) {
                return String.format("优秀 (%.0f分)", value);
            } else if (normalizedScore >= 0.8) {
                return String.format("良好 (%.0f分)", value);
            } else if (normalizedScore >= 0.6) {
                return String.format("及格 (%.0f分)", value);
            } else {
                return String.format("不及格 (%.0f分)", value);
            }
        }
        
        Python优势：
        - isinstance()比Java的instanceof更简洁
        - elif比else if更简洁
        - f-string比String.format()更直观
        - 海象运算符减少重复计算
        
        Args:
            score: 分数值 (0-100) - 类似Java的Number参数
            
        Returns:
            分数等级描述 - 类似Java的String返回值
            
        Raises:
            ValueError: 当分数超出有效范围时 - 类似Java的IllegalArgumentException
        """
        # === 类型检查（对比Java的instanceof） ===
        if not isinstance(score, (int, float)):  # Python: isinstance()，Java: instanceof
            raise TypeError(f"分数必须是数字类型，得到: {type(score)}")
        
        # === 范围检查（对比Java的条件判断） ===
        if not 0 <= score <= 100:  # Python: 链式比较，Java: score >= 0 && score <= 100
            raise ValueError(f"分数必须在0-100之间，得到: {score}")
        
        # === 海象运算符 (Python 3.8+) vs Java传统赋值 ===
        # Python: 在条件中赋值和判断
        if (normalized_score := score / 100) >= 0.9:  # Java需要先赋值再判断
            return f"优秀 ({score}分)"  # Python: f-string，Java: String.format()
        elif normalized_score >= 0.8:  # Python: elif，Java: else if
            return f"良好 ({score}分)"
        elif normalized_score >= 0.6:
            return f"及格 ({score}分)"
        else:  # 默认情况，Java和Python相同
            return f"不及格 ({score}分)"
    
    # 测试条件语句
    test_scores = [95, 85, 70, 45]
    for score in test_scores:
        try:
            result = evaluate_score(score)
            print(f"✓ {result}")
        except (ValueError, TypeError) as e:
            print(f"✗ 错误: {e}")

def demonstrate_advanced_loops() -> None:
    """演示高级循环最佳实践 - 对比Java的循环和Stream API
    
    Java对比要点：
    - Python列表推导式 vs Java Stream API
    - Python生成器 vs Java Iterator/Stream
    - Python的for-in vs Java的enhanced for loop
    - Python的enumerate vs Java的手动索引
    - Python的zip vs Java的多重循环
    
    Java等价写法示例：
    // Java Stream API（类似Python推导式）
    List<Integer> squares = data.stream()
        .filter(x -> x % 2 == 0)
        .map(x -> x * x)
        .collect(Collectors.toList());
    
    // Java传统循环（对比Python的for-in）
    for (int i = 0; i < names.size(); i++) {
        String name = names.get(i);
        int age = ages.get(i);
        // 处理逻辑
    }
    """
    print("\n======== 2. 高级循环和迭代 ========")
    
    # === 列表推导式 vs Java Stream API ===
    data = list(range(1, 11))
    
    # Python推导式 vs Java Stream filter + map
    # Java: data.stream().filter(x -> x % 2 == 0).map(x -> x * x).collect(Collectors.toList())
    squares = [x**2 for x in data if x % 2 == 0]  # Python: 一行完成过滤和映射
    print(f"✓ 偶数平方: {squares}")
    
    # === 字典推导式 vs Java Stream Collectors.toMap ===
    # Java: scores.stream().collect(Collectors.toMap(score -> score, score -> grade(score)))
    score_grades = {score: 'A' if score >= 90 else 'B' if score >= 80 else 'C' 
                   for score in [95, 85, 75, 65]}  # Python: 字典推导式更简洁
    print(f"✓ 分数等级映射: {score_grades}")
    
    # === 集合推导式 vs Java Stream distinct ===
    # Java: IntStream.range(0, 20).map(x -> x % 3).boxed().collect(Collectors.toSet())
    unique_remainders = {x % 3 for x in range(20)}  # Python: 集合推导式自动去重
    print(f"✓ 唯一余数: {unique_remainders}")
    
    # === 生成器表达式 vs Java Iterator/Stream（内存高效）===
    def demonstrate_generators() -> Generator[int, None, None]:
        """演示生成器的内存效率 - 对比Java的Iterator
        
        Java等价写法：
        public Iterator<Integer> demonstrateIterator() {
            return new Iterator<Integer>() {
                private int current = 0;
                public boolean hasNext() { return current < 1000000; }
                public Integer next() {
                    while (current < 1000000) {
                        if (current % 1000 == 0) return current++;
                        current++;
                    }
                    throw new NoSuchElementException();
                }
            };
        }
        
        Python优势：
        - yield关键字比Java的Iterator接口更简洁
        - 自动实现迭代器协议
        - 惰性求值，节省内存
        """
        for i in range(1000000):  # Python: range()本身就是惰性的
            if i % 1000 == 0:
                yield i  # Python: yield比Java的next()更简洁
    
    # === 生成器 + enumerate vs Java的复杂循环 ===
    # Java需要手动计数和迭代器
    large_numbers = list(x for i, x in enumerate(demonstrate_generators()) if i < 5)
    print(f"✓ 大数据集前5个值: {large_numbers}")
    
    # === enumerate 和 zip vs Java的多重循环 ===
    names = ['Alice', 'Bob', 'Charlie']
    ages = [25, 30, 35]
    scores = [95, 87, 92]
    
    # Python的zip + enumerate vs Java的传统索引循环
    # Java等价写法：
    # for (int i = 0; i < Math.min(names.size(), Math.min(ages.size(), scores.size())); i++) {
    #     String name = names.get(i);
    #     int age = ages.get(i);
    #     int score = scores.get(i);
    #     System.out.printf("第%d位: %s (%d岁) - %d分%n", i+1, name, age, score);
    # }
    for i, (name, age, score) in enumerate(zip(names, ages, scores), 1):  # Python: 多重解包更优雅
        print(f"✓ 第{i}位: {name} ({age}岁) - {score}分")  # Python: f-string比Java的printf更直观

@contextmanager
def safe_file_operation(filename: str) -> Generator[Path, None, None]:
    """安全文件操作上下文管理器"""
    temp_file = None
    try:
        # 创建临时文件
        temp_file = Path(tempfile.mktemp(suffix='.json'))
        logger.info(f"创建临时文件: {temp_file}")
        yield temp_file
    except Exception as e:
        logger.error(f"文件操作失败: {e}")
        raise
    finally:
        # 清理临时文件
        if temp_file and temp_file.exists():
            temp_file.unlink()
            logger.info(f"清理临时文件: {temp_file}")

def demonstrate_context_managers() -> None:
    """演示上下文管理器最佳实践"""
    print("\n======== 3. 上下文管理器和资源管理 ========")
    
    # 自定义上下文管理器
    try:
        with safe_file_operation("test.json") as temp_file:
            # 写入测试数据
            test_data = {"message": "Hello, World!", "numbers": [1, 2, 3]}
            temp_file.write_text(json.dumps(test_data, indent=2))
            
            # 读取并验证
            content = json.loads(temp_file.read_text())
            print(f"✓ 文件操作成功: {content['message']}")
    except Exception as e:
        print(f"✗ 文件操作失败: {e}")
    
    # 使用 suppress 忽略特定异常
    with suppress(FileNotFoundError):
        Path("non_existent_file.txt").unlink()
        print("✓ 安全删除不存在的文件")

def demonstrate_exception_handling() -> ProcessingResult:
    """演示企业级异常处理"""
    print("\n======== 4. 企业级异常处理 ========")
    
    def risky_operation(value: Any) -> float:
        """可能失败的操作"""
        if isinstance(value, str):
            return float(value)
        elif isinstance(value, (int, float)):
            return 100.0 / value
        else:
            raise TypeError(f"不支持的类型: {type(value)}")
    
    test_values = ["42.5", 10, 0, "invalid", None]
    results = []
    
    for value in test_values:
        try:
            result = risky_operation(value)
            results.append(ProcessingResult(
                status=ProcessingStatus.COMPLETED,
                data=result,
                metadata={"input": value, "type": type(value).__name__}
            ))
            print(f"✓ 处理成功: {value} -> {result}")
            
        except ZeroDivisionError:
            error_msg = "除零错误"
            results.append(ProcessingResult(
                status=ProcessingStatus.FAILED,
                error_message=error_msg,
                metadata={"input": value, "error_type": "ZeroDivisionError"}
            ))
            print(f"✗ {error_msg}: {value}")
            
        except ValueError as e:
            error_msg = f"值错误: {e}"
            results.append(ProcessingResult(
                status=ProcessingStatus.FAILED,
                error_message=error_msg,
                metadata={"input": value, "error_type": "ValueError"}
            ))
            print(f"✗ {error_msg}")
            
        except TypeError as e:
            error_msg = f"类型错误: {e}"
            results.append(ProcessingResult(
                status=ProcessingStatus.FAILED,
                error_message=error_msg,
                metadata={"input": value, "error_type": "TypeError"}
            ))
            print(f"✗ {error_msg}")
            
        except Exception as e:
            error_msg = f"未知错误: {e}"
            results.append(ProcessingResult(
                status=ProcessingStatus.FAILED,
                error_message=error_msg,
                metadata={"input": value, "error_type": type(e).__name__}
            ))
            print(f"✗ {error_msg}")
    
    # 统计结果
    successful = sum(1 for r in results if r.status == ProcessingStatus.COMPLETED)
    failed = len(results) - successful
    
    return ProcessingResult(
        status=ProcessingStatus.COMPLETED,
        data={"successful": successful, "failed": failed, "total": len(results)},
        metadata={"results": results}
    )

def demonstrate_pattern_matching() -> None:
    """演示模式匹配 (Python 3.10+)"""
    print("\n======== 5. 模式匹配 (Python 3.10+) ========")
    
    if sys.version_info >= (3, 10):
        def process_data(data: Any) -> str:
            """使用模式匹配处理不同类型的数据"""
            match data:
                case int() if data > 0:
                    return f"正整数: {data}"
                case int() if data < 0:
                    return f"负整数: {data}"
                case 0:
                    return "零"
                case str() if data.isdigit():
                    return f"数字字符串: {data}"
                case str():
                    return f"普通字符串: {data}"
                case list() | tuple() if len(data) > 0:
                    return f"非空序列，长度: {len(data)}"
                case []:
                    return "空列表"
                case dict() if data:
                    return f"非空字典，键: {list(data.keys())}"
                case {}:
                    return "空字典"
                case _:
                    return f"未知类型: {type(data)}"
        
        test_data = [42, -10, 0, "123", "hello", [1, 2, 3], [], {"key": "value"}, {}]
        for item in test_data:
            result = process_data(item)
            print(f"✓ {result}")
    else:
        print("✗ 模式匹配需要 Python 3.10+，当前版本: {}.{}".format(*sys.version_info[:2]))

def run_comprehensive_tests() -> None:
    """运行综合测试套件"""
    print("\n======== 6. 综合测试套件 ========")
    
    test_functions = [
        ("条件语句测试", demonstrate_enhanced_conditionals),
        ("循环迭代测试", demonstrate_advanced_loops),
        ("上下文管理器测试", demonstrate_context_managers),
        ("模式匹配测试", demonstrate_pattern_matching),
    ]
    
    passed = 0
    total = len(test_functions)
    
    for test_name, test_func in test_functions:
        try:
            test_func()
            print(f"✓ {test_name} 通过")
            passed += 1
        except Exception as e:
            print(f"✗ {test_name} 失败: {e}")
    
    # 异常处理测试
    try:
        exception_result = demonstrate_exception_handling()
        if exception_result.status == ProcessingStatus.COMPLETED:
            stats = exception_result.data
            print(f"✓ 异常处理测试 通过 (成功: {stats['successful']}, 失败: {stats['failed']})")
            passed += 1
        else:
            print("✗ 异常处理测试 失败")
    except Exception as e:
        print(f"✗ 异常处理测试 失败: {e}")
    
    total += 1  # 包含异常处理测试
    
    print(f"\n测试结果: {passed}/{total} 通过")
    print("所有企业级控制流最佳实践演示完成!")

if __name__ == "__main__":
    run_comprehensive_tests()